package fr.lelouet.stress



import org.slf4j.LoggerFactory

/**
 * 
 * @author guillaume
 *
 */
class DiskTools {

	private static final org.slf4j.Logger logger = LoggerFactory.getLogger(DiskTools.class)

	/** return the number of writes that have been done to the system's filessystem on block devices, since startup.<br />
	 * Does not consider the data written in a cache*/
	static long systemWrites() {
		def proc = [
			"bash",
			"-c",
			"vmstat -D | head -n9 | tail -n1 | sed 's/^[ \\t]*//' | sed 's/ .*//'"
		].execute()
		proc.waitFor()
		if(proc.exitValue()  == 0) {
			long ret = proc.in.text as Long
			proc.errorStream.close()
			proc.inputStream.close()
			proc.outputStream.close()
			return ret
		}
		else return -1
	}

	/** writes blocs of bytes to a file, then wait for the system to sync. Should have a sync before it !*/
	static boolean syncStress(String fileName, int number, String size="1k") {
		if(!asyncStress(fileName, number, size)) {
			return false
		}
		return systemSync()
	}

	/** ask the system to write bytes in a file*/
	static boolean asyncStress(String fileName, int number, String size="1k") {
		def proc = "dd if=/dev/zero of=$fileName bs=$size count=$number oflag=direct,sync".toString().execute()
		proc.waitFor()
		if(proc.exitValue() == 0) {
			proc.errorStream.close()
			proc.inputStream.close()
			proc.outputStream.close()
			return true
		}
		return false
	}

	/** forces the system so sync, writting data in cache*/
	static boolean systemSync() {
		def proc="sync".execute()
		proc.waitFor()
		if(proc.exitValue() == 0) {
			proc.errorStream.close()
			proc.inputStream.close()
			proc.outputStream.close()
			return true
		}
		return false
	}

	/** @return the number of bytes corresponding to the given number of blocs, each bloc being of blocSize size*/
	static long byteswritten(String blocSize, long blocNB=1) {
		long blocBytes = -1
		if(blocSize.endsWith("k")) {
			blocBytes=1024*blocSize.substring(0, blocSize.size()-1).toInteger()
		} else if(blocSize.endsWith("M")){
			blocBytes=1024*1024*blocSize.substring(0, blocSize.size()-1).toInteger()
		} else if(blocSize.endsWith("G")){
			blocBytes=1024*1024*1024*blocSize.substring(0, blocSize.size()-1).toInteger()
		} else if(blocSize.isInteger()) {
			blocBytes = blocSize.toInteger()
		}
		return blocBytes>0?(blocBytes*blocNB):-1
	}
}
